package com.tuanzi.loan.web.bean.family.sms;

import com.base.common.util.RandomUtils;
import com.google.common.collect.Lists;
import com.tuanzi.loan.business.constants.DictionaryCode;
import com.tuanzi.loan.business.entity.shortlink.ShortLink;
import com.tuanzi.loan.business.entity.sms.SmsCalculateTask;
import com.tuanzi.loan.business.entity.sms.SmsCalculateTaskStatus;
import com.tuanzi.loan.business.entity.sms.SmsSendTask;
import com.tuanzi.loan.business.entity.sms.SmsSendTaskStatus;
import com.tuanzi.loan.business.entity.system.Dictionary;
import com.tuanzi.loan.business.service.shortlink.ShortLinkService;
import com.tuanzi.loan.business.service.sms.SmsCalculateTaskService;
import com.tuanzi.loan.business.service.sms.SmsSendTaskService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.exception.ValidateException;
import com.tuanzi.loan.web.configuration.JSFInfoBean;
import com.tuanzi.server.loan_base.constant.sms.LoanSmsLinkType;
import com.tuanzi.server.loan_base.constant.sms.SmsPlatformChannel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.primefaces.event.FileUploadEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.tuanzi.loan.business.constants.DictionaryCode.*;
import static com.tuanzi.server.loan_base.constant.sms.SmsPlatformChannel.ZHENG_TONG_MULTIMEDIA_MESSAGE;

@Data
@Slf4j
@Debug
@Component
@ViewScoped
@EqualsAndHashCode(callSuper = true)
public class SendSmsBean extends JSFInfoBean<SmsSendTask> {

	private static final long serialVersionUID = 5422051183627539512L;

	@Autowired
	private SmsCalculateTaskService smsCalculateTaskService;
	@Autowired
	private SmsSendTaskService smsSendTaskService;
	@Autowired
	private ShortLinkService shortLinkService;

	@Value("${shortLink-host}")
	private String shortLinkHost;

	private Integer selectedTemplateGroup;
	private List<Dictionary> smsTemplates;
	private String template;
	private String activityName;
	private String var1;
	private String var2;
	private String var3;
	private String var4;
	private ShortLink shortLinkEntity = new ShortLink();
	private String shortLink;
	private List<SendSmsVo> sendSmsVos;
	private String templateContent;
	private boolean disableButton;

	private static final Pattern PATTERN = Pattern.compile("https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]");

	@PostConstruct
	private void init() {
		String id = getParamFromRequest("id");

		if (StringUtils.isBlank(id)) {
			forceRedirect("/views/family/user-info/send-sms/calculate-sms.xhtml");
			return;
		}

		sendSmsVos = smsCalculateTaskService.findAllByIdsIn(Arrays.asList(StringUtils.split(id, ",")).stream().map(NumberUtils::toLong).collect(Collectors.toList()))
				.parallelStream().map(x -> {
					SendSmsVo sendSmsVo = new SendSmsVo();
					sendSmsVo.setCalculateTaskId(x.getId());
					sendSmsVo.setCalculateTaskName(x.getName());
					sendSmsVo.setCalculateTaskPhoneCount(x.getPhoneCount());
					return sendSmsVo;
				}).collect(Collectors.toList());

		if (CollectionUtils.isEmpty(sendSmsVos)) {
			forceRedirect("/views/family/user-info/send-sms/calculate-sms.xhtml");
			return;
		}

		sendSmsVos.stream().forEach(x -> {
			SmsSendTask smsSendTask = smsSendTaskService.addSmsSendTask(x.getCalculateTaskId());
			x.setSendTaskId(smsSendTask.getId());
		});
	}

	@Override
	protected List<String> getDictionaryCodes() {
		return Lists.newArrayList(PLATFORM, SMS_TEMPLATE_GROUP, SMS_TEMPLATE_BLACK_LIST, SMS_TEMPLATE_MARKETING, 
				SMS_TEMPLATE_PULL_BACK, SMS_PLATFORM_CHANNEL, SMS_TEMPLATE_ID);
	}

	public void onSend() {
		sendSmsVos.parallelStream().forEach(x -> {
			if (x.getPlatformChannel() == null) {
				throw new ValidateException(String.format("[%s]请选择短信平台渠道", x.getCalculateTaskName()));
			}
			if(x.getExecuteTime() != null && x.getExecuteTime().before(new Date())){
				throw new ValidateException(String.format("[%s]计划发送时间不能早于当前时间", x.getCalculateTaskName()));
			}
			if(x.getPlatformChannel() == SmsPlatformChannel.OUYI_SCREEN.getId()){
				if(StringUtils.isBlank(x.getTemplateId())){
					throw new ValidateException(String.format("[%s]请选择短信平台模板编号", x.getCalculateTaskName()));
				}
				if(StringUtils.isNotBlank(x.getContent())){
					throw new ValidateException(String.format("[%s]该平台不需要输入短信文案", x.getCalculateTaskName()));
				}
			}
			if(StringUtils.isBlank(x.getContent()) && x.getPlatformChannel() != SmsPlatformChannel.OUYI_SCREEN.getId()){
				throw new ValidateException(String.format("[%s]请输入短信文案", x.getCalculateTaskName()));
			}
			if (StringUtils.length(x.getContent()) > 70) {
				throw new ValidateException(String.format("[%s]短信文案字数最大为70字", x.getCalculateTaskName()));
			}
			if(StringUtils.isNotBlank(x.getContent())){
				if(x.getPlatformChannel() == SmsPlatformChannel.MENGWANG.getId()){
					if(x.getContent().contains("【") || x.getContent().contains("】")){
						throw new ValidateException(String.format("[%s]梦网平台不用带短信签名", x.getCalculateTaskName()));
					}
				}else if(x.getPlatformChannel() == SmsPlatformChannel.ZHENG_TONG_MULTIMEDIA_MESSAGE.getId()){
					if(!x.getContent().startsWith("http")){
						throw new ValidateException(String.format("[%s]一道正通彩信的文案只能是链接", x.getCalculateTaskName()));
					}
				}else{
					if(!x.getContent().contains("【") || !x.getContent().contains("】")) {
						throw new ValidateException(String.format("[%s]请输入短信签名", x.getCalculateTaskName()));
					}
				}
			}
			if (x.getExecuteTime() == null) {
				x.setExecuteTime(new Date());
			}

			SmsCalculateTask smsCalculateTask = smsCalculateTaskService.findOne(x.getCalculateTaskId());

			if(x.getPlatformChannel() == SmsPlatformChannel.DINGHAN.getId() && Objects.nonNull(smsCalculateTask.getPhoneCount())
					&& smsCalculateTask.getPhoneCount() > 70000){ //鼎汉平台限制发送70000条短信
				throw new ValidateException(String.format("[%s]鼎汉平台每次最多提交7万条短信，请重新计算号码包。", x.getCalculateTaskName()));
			}

			if(x.getPlatformChannel() == SmsPlatformChannel.SHENGSHIXINAN.getId() && Objects.nonNull(smsCalculateTask.getPhoneCount())
					&& smsCalculateTask.getPhoneCount() > 40000){ //盛世新安平台限制发送4万条
				throw new ValidateException(String.format("[%s]盛世新安平台每次最多提交4万条短信，请重新计算号码包。", x.getCalculateTaskName()));
			}

			if(x.getPlatformChannel() == SmsPlatformChannel.YUNFENG_WANGDAI.getId() || x.getPlatformChannel() == SmsPlatformChannel.YUNFENG_WANGDAI_NEW.getId()){
				if(Objects.nonNull(smsCalculateTask.getPhoneCount()) && smsCalculateTask.getPhoneCount() > 100000){
					throw new ValidateException(String.format("[%s]云锋网贷平台每次最多提交10万条短信，请重新计算号码包。", x.getCalculateTaskName()));
				}

			}

			if(x.getPlatformChannel() == ZHENG_TONG_MULTIMEDIA_MESSAGE.getId() && StringUtils.isBlank(x.getMmsPicUrl())){  //一道正通彩信图片
				throw new ValidateException(String.format("[%s]请上传彩信图片", x.getCalculateTaskName()));
			}

			x.setStatus(SmsSendTaskStatus.READY_SEND);
			if (smsCalculateTask.getStatus() != SmsCalculateTaskStatus.CALCULATE_DONE) {
				x.setStatus(SmsSendTaskStatus.WAITING_CALCULATE_DONE);
			}

			SmsSendTask smsSendTask = smsSendTaskService.findOne(x.getSendTaskId());
			smsSendTask.setStatus(x.getStatus());
			smsSendTask.setContent(x.getContent());
			smsSendTask.setExecuteTime(x.getExecuteTime());
			smsSendTask.setPlatformChannel(x.getPlatformChannel());
			smsSendTask.setTemplateId(x.getTemplateId());
			smsSendTask.setMmsPicUrl(x.getMmsPicUrl());

			String shortLink = x.getShortLink();
			// 避免在发送短信时不生成短链直接复制文案发送，通过文案中的显示短链找回短链
			if (StringUtils.isEmpty(shortLink)) {
				String displayShortLink = extractDisplayShortLink(smsSendTask.getContent());
				if (StringUtils.isNotEmpty(displayShortLink)) {
					ShortLink sl = shortLinkService.findByDisplayedShortLink(displayShortLink);
					if (sl != null) {
						shortLink = sl.getShortLink();
					} else {
						log.warn("从发送任务[]的文案中，提取出来的短网址[]，无法找到对应的短链。", smsSendTask.getId(), displayShortLink);
					}
				}
			}
			smsSendTask.setShortLink(shortLink);

			smsCalculateTask.setSentCount(smsCalculateTask.getSentCount() + 1);
			smsSendTaskService.saveOrUpdate(smsSendTask);
			smsCalculateTaskService.saveOrUpdate(smsCalculateTask);
		});
		disableButton = true;
		addInfoMessage("操作成功,任务已加入发送队列");
	}

	public void onSelectSmsTemplateGroup() {
		if (selectedTemplateGroup == null) {
			smsTemplates = Lists.newArrayList();
			return;
		}

		switch (selectedTemplateGroup) {
		case 1: // 甲方营销
			smsTemplates = getDictionaries().get(DictionaryCode.SMS_TEMPLATE_MARKETING);
			break;
		case 2:// 老用户回拉
			smsTemplates = getDictionaries().get(DictionaryCode.SMS_TEMPLATE_PULL_BACK);
			break;
		case 3:// 网贷黑名单
			smsTemplates = getDictionaries().get(DictionaryCode.SMS_TEMPLATE_BLACK_LIST);
			break;
		default:
			log.warn("switch条件不匹配 : {}", selectedTemplateGroup);
			break;
		}
	}

	public void onUpdateTemplate() {
		String content = StringUtils.EMPTY;

		content = StringUtils.replace(template, "{0}", StringUtils.isBlank(activityName) ? "菠萝贷" : activityName);
		content = StringUtils.replace(content, "{1}", var1);
		content = StringUtils.replace(content, "{2}", var2);
		content = StringUtils.replace(content, "{3}", var3);
		content = StringUtils.replace(content, "{4}", var4);
		$.setContent(content);
	}

	@Transactional
	public void onTransferLink(Long smsSendTaskId) {

		if($.getLinkType() == null) {
			addErrorMessage("请选择短信链接类型");
			return;
		}

		if(shortLinkEntity.getEnvironment() == null){
			addErrorMessage("请选择作用环境");
			return;
		}

		if (StringUtils.isBlank(shortLinkEntity.getUrl())) {
			addErrorMessage("请输入短信链接");
			return;
		}

		if (StringUtils.isBlank(shortLinkEntity.getActivity())) {
			addErrorMessage("请输入项目");
			return;
		}

		if (StringUtils.isBlank(shortLinkEntity.getMemo())) {
			addErrorMessage("请输入备注");
			return;
		}

		String url = shortLinkEntity.getUrl();
		if($.getLinkType() == LoanSmsLinkType.LOAN_LINK) { //如果是菠萝贷链接，链接拼上短信任务ID参数，追踪埋点数据
			if (!url.contains("sms_task_id")) {
				if (url.contains("?")) {
					url = url + "&sms_task_id=" + smsSendTaskId;
				} else {
					url = url + "?sms_task_id=" + smsSendTaskId;
				}
			}
		}

		String slink = RandomUtils.getRandomMixString(new Random().nextInt(2) + 4);
		shortLinkEntity.setUrl(url);
		shortLinkEntity.setShortLink(slink);
		shortLinkEntity.setCtime(new Date());
		shortLinkService.saveOrUpdate(shortLinkEntity);

		shortLink = shortLinkHost + shortLinkEntity.getShortLink();

		//短信任务保存短链接
		$.setShortLink(shortLinkEntity.getShortLink());
		smsSendTaskService.saveOrUpdate($);
	}

	/**
	 * 生成短链
	 */
	public void generateShortLink() {
		if (sendSmsVos.parallelStream().filter(x -> x.getPlatformChannel() == null).count() > 0) {
			addErrorMessage("请先选择短信渠道");
			return;
		}

		if (sendSmsVos.parallelStream().filter(x -> StringUtils.isEmpty(x.getShortLink())).count() > 0) {
			addErrorMessage("生成短链前请确保已输入对应链接");
			return;
		}

		sendSmsVos.parallelStream().forEach(x -> {
			ShortLink shortLink = new ShortLink();
			shortLink.setActivity(x.getCalculateTaskName());
			Dictionary dictionary = getDictionaries().get(DictionaryCode.SMS_PLATFORM_CHANNEL).parallelStream()
					.filter(y -> y.getValue1().equalsIgnoreCase(x.getPlatformChannel().toString())).findFirst().get();
			shortLink.setMemo(dictionary.getName());
			shortLink.setUrl(x.getShortLink());
			String slink = RandomUtils.getRandomMixString(new Random().nextInt(2) + 4);
			shortLink.setShortLink(slink);
			shortLink.setCtime(new Date());
			String displayedShortLink = shortLinkHost + shortLink.getShortLink();
			shortLink.setDisplayedShortLink(displayedShortLink);
			shortLink.setEnvironment(0);
			shortLink.setIsUsedLink(1);
			shortLinkService.saveOrUpdate(shortLink);

			x.setShortLink(shortLink.getShortLink());
			x.setDisplayShortLink(displayedShortLink);
		});
	}

	/**
	 * 填充短信模板
	 */
	public void fillTemplateContent() {
		if (StringUtils.isBlank(templateContent)) {
			addErrorMessage("不存在短信模板");
			return;
		}

		sendSmsVos.parallelStream().forEach(x -> {
			x.setContent(StringUtils.replace(templateContent, "{short-link}", x.getDisplayShortLink()));
		});
	}

	private static String extractDisplayShortLink(String content) {
		Matcher matcher = PATTERN.matcher(content);
		if (matcher.find()) {
			return matcher.group();
		}
		return null;
	}

	@Data
	public class SendSmsVo {

		private Long calculateTaskId;

		private String calculateTaskName;

		private Integer calculateTaskPhoneCount;

		private Long sendTaskId;

		private String shortLink;

		private String displayShortLink;

		private Boolean hasSplitedTask;

		private Integer phoneCount;

		private Date executeTime;

		private Integer product;

		private String content;

		private Integer platformChannel;

		private String activityId;

		private Integer channel;

		private String templateId;

		private String mmsPicUrl;

		private SmsSendTaskStatus status;

		/**
		 * 上传彩信图片到七牛
		 * @param event
		 */
		public void uploadImage(FileUploadEvent event) {
			String picUrl = uploadImg(event.getFile());
			this.setMmsPicUrl(picUrl);
		}
	}
}
